<template>
  <view v-if="visible" class="app-loading" :class="loadingClass" :style="loadingStyle">
    <!-- 全屏加载 -->
    <view v-if="type === 'fullscreen'" class="app-loading__fullscreen">
      <view class="app-loading__spinner">
        <view class="app-loading__spinner-item" v-for="item in 8" :key="item"></view>
      </view>
      <text v-if="text" class="app-loading__text">{{ text }}</text>
    </view>

    <!-- 局部加载 -->
    <view v-else-if="type === 'inline'" class="app-loading__inline">
      <view class="app-loading__dots">
        <view class="app-loading__dot"></view>
        <view class="app-loading__dot"></view>
        <view class="app-loading__dot"></view>
      </view>
      <text v-if="text" class="app-loading__text--inline">{{ text }}</text>
    </view>

    <!-- 骨架屏加载 -->
    <view v-else-if="type === 'skeleton'" class="app-loading__skeleton">
      <slot name="skeleton">
        <!-- 默认骨架屏 -->
        <view class="skeleton-item">
          <view class="skeleton-avatar"></view>
          <view class="skeleton-content">
            <view class="skeleton-title"></view>
            <view class="skeleton-line"></view>
            <view class="skeleton-line short"></view>
          </view>
        </view>
      </slot>
    </view>

    <!-- 遮罩加载 -->
    <view v-else-if="type === 'overlay'" class="app-loading__overlay">
      <view class="app-loading__mask"></view>
      <view class="app-loading__content">
        <view class="app-loading__spinner">
          <view class="app-loading__spinner-item" v-for="item in 8" :key="item"></view>
        </view>
        <text v-if="text" class="app-loading__text">{{ text }}</text>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed } from 'vue'

// Props
interface Props {
  visible?: boolean
  type?: 'fullscreen' | 'inline' | 'skeleton' | 'overlay'
  text?: string
  size?: 'small' | 'medium' | 'large'
  color?: string
  backgroundColor?: string
  zIndex?: number
  customClass?: string
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  type: 'fullscreen',
  text: '',
  size: 'medium',
  color: '#1890ff',
  backgroundColor: 'rgba(255, 255, 255, 0.9)',
  zIndex: 999,
  customClass: ''
})

// 计算属性
const loadingClass = computed(() => {
  return [
    `app-loading--${props.type}`,
    `app-loading--${props.size}`,
    props.customClass
  ]
})

const loadingStyle = computed(() => {
  if (props.type === 'overlay' || props.type === 'fullscreen') {
    return {
      zIndex: props.zIndex,
      backgroundColor: props.type === 'overlay' ? props.backgroundColor : 'transparent'
    }
  }
  return {}
})
</script>

<style lang="scss" scoped>
.app-loading {
  display: flex;
  align-items: center;
  justify-content: center;

  // 全屏加载
  &__fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.9);
    flex-direction: column;
    z-index: 999;
  }

  // 局部加载
  &__inline {
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }

  // 遮罩加载
  &__overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: inherit;
  }

  &__mask {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: v-bind(backgroundColor);
    backdrop-filter: blur(2px);
  }

  &__content {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 24px;
    background: #ffffff;
    border-radius: 12px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  }

  // 旋转加载器
  &__spinner {
    position: relative;
    width: 40px;
    height: 40px;
    animation: spinnerRotate 1.2s linear infinite;
  }

  &__spinner-item {
    position: absolute;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: v-bind(color);
    animation: spinnerBounce 1.2s ease-in-out infinite;

    &:nth-child(1) { top: 0; left: 17px; animation-delay: 0s; }
    &:nth-child(2) { top: 5px; right: 5px; animation-delay: 0.1s; }
    &:nth-child(3) { bottom: 5px; right: 5px; animation-delay: 0.2s; }
    &:nth-child(4) { bottom: 0; left: 17px; animation-delay: 0.3s; }
    &:nth-child(5) { bottom: 5px; left: 5px; animation-delay: 0.4s; }
    &:nth-child(6) { top: 17px; left: 0; animation-delay: 0.5s; }
    &:nth-child(7) { top: 17px; right: 0; animation-delay: 0.6s; }
    &:nth-child(8) { top: 5px; left: 5px; animation-delay: 0.7s; }
  }

  // 点状加载器
  &__dots {
    display: flex;
    gap: 4px;
  }

  &__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: v-bind(color);
    animation: dotBounce 1.4s ease-in-out infinite both;

    &:nth-child(1) { animation-delay: -0.32s; }
    &:nth-child(2) { animation-delay: -0.16s; }
    &:nth-child(3) { animation-delay: 0s; }
  }

  // 文本样式
  &__text {
    font-size: 14px;
    color: #666;
    text-align: center;
    margin-top: 16px;
  }

  &__text--inline {
    font-size: 12px;
    color: #666;
  }

  // 尺寸样式
  &--small {
    .app-loading__spinner {
      width: 24px;
      height: 24px;
    }

    .app-loading__spinner-item {
      width: 4px;
      height: 4px;
    }

    .app-loading__dot {
      width: 6px;
      height: 6px;
    }

    .app-loading__text {
      font-size: 12px;
    }
  }

  &--large {
    .app-loading__spinner {
      width: 56px;
      height: 56px;
    }

    .app-loading__spinner-item {
      width: 8px;
      height: 8px;
    }

    .app-loading__dot {
      width: 10px;
      height: 10px;
    }

    .app-loading__text {
      font-size: 16px;
    }
  }

  // 骨架屏样式
  &__skeleton {
    width: 100%;
  }
}

.skeleton-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;

  .skeleton-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: skeletonLoading 1.5s infinite;
  }

  .skeleton-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;

    .skeleton-title {
      height: 16px;
      width: 60%;
      background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
      background-size: 200% 100%;
      animation: skeletonLoading 1.5s infinite;
      border-radius: 4px;
    }

    .skeleton-line {
      height: 12px;
      width: 100%;
      background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
      background-size: 200% 100%;
      animation: skeletonLoading 1.5s infinite;
      border-radius: 4px;

      &.short {
        width: 40%;
      }
    }
  }
}

// 动画
@keyframes spinnerRotate {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes spinnerBounce {
  0%, 100% {
    transform: scale(0);
    opacity: 0.5;
  }
  50% {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes dotBounce {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

@keyframes skeletonLoading {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}
</style>